package tom.yang.testaar;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.WeakHashMap;

/**
 * 阴影管理器
 * @author yangdibo
 */
public class ShadowBuilder {
    public static String KEY_FORMAT = "key_%d_%d_%d_%d_%d_%d_%s_%d_%d";
    /**
     * 使用虚引用来管理内存
     */
    private WeakHashMap<String,Drawable> mCache = new WeakHashMap<>();


    public Drawable getDrawable(int width , int height , int shadowRadius, int shadowColor, int contentRadius , int bgColor) {
        return getDrawable(width, height, shadowRadius, 0, 0, shadowColor,
                new Rect(shadowRadius,shadowRadius,width - shadowRadius,height - shadowRadius), contentRadius, bgColor);
    }

    public Drawable getDrawable(int width , int height , int shadowRadius, int shadowColor,
                                int paddingWidth , int paddingHeight , int contentRadius , int bgColor) {

        return getDrawable(width, height, shadowRadius, 0, 0, shadowColor,
                new Rect(paddingWidth,paddingHeight,width - paddingWidth,height - paddingHeight), contentRadius, bgColor);
    }


    public Drawable getDrawable(int width , int height , int shadowRadius, int shadowColor, Rect rect , int contentRadius , int bgColor) {
        return getDrawable(width, height, shadowRadius, 0, 0, shadowColor, rect, contentRadius, bgColor);
    }

    public Drawable getDrawable(int shadowWidth, int shadowHeight , int shadowRadius,
                                int offsetX, int offsetY, int shadowColor,
                                Rect rect, int contentRadius, int bgColor) {

        String key = String.format(KEY_FORMAT, shadowWidth,shadowHeight,shadowRadius,offsetX,offsetY,
                shadowColor,String.valueOf(rect),contentRadius,bgColor);
        Log.e("TAG", "getDrawable: " + key );
        Drawable drawable = mCache.get(key);
        if(drawable == null) {
            drawable = generateShadowDrawable(Bitmap.Config.ARGB_8888, shadowWidth, shadowHeight,
                    shadowRadius, offsetX, offsetY, shadowColor, rect, contentRadius, bgColor);
            mCache.put(key, drawable);
        }
        return drawable;
    }

    /**
     * 生成一个有阴影的Drawable,这个阴影实际上是一个由Bitmap组成的Drawable
     * @param config 一定要有透明度的Config
     * @param shadowWidth 包含阴影的总宽度
     * @param shadowHeight 包含阴影的总高度
     * @param shadowRadius 阴影宽度
     * @param offsetX 阴影x轴位移
     * @param offsetY 阴影y轴位移
     * @param shadowColor 阴影起始颜色
     * @param rect 内容范围
     * @param contentRadius 内容的圆角
     * @param bgColor 内容背景颜色
     * @return
     */
    public Drawable generateShadowDrawable(Bitmap.Config config , int shadowWidth, int shadowHeight ,
                                           int shadowRadius, int offsetX, int offsetY, int shadowColor,
                                           Rect rect, int contentRadius,
                                           int bgColor) {
        Bitmap bitmap = Bitmap.createBitmap(shadowWidth, shadowHeight, config);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.TRANSPARENT);

        Paint paint = new Paint();
        paint.setShadowLayer(shadowRadius, offsetX, offsetY, shadowColor);
        canvas.drawRoundRect(new RectF(rect), contentRadius, contentRadius, paint);

        Paint newPaint = new Paint();
        newPaint.setColor(bgColor);
        canvas.drawRoundRect(new RectF(rect), contentRadius, contentRadius, newPaint);
        return new ShadowDrawable(bitmap,new Rect(0,0,shadowWidth,shadowHeight),offsetX,offsetY);
    }

    /**
     * 生成一个有阴影的Drawable,这个阴影实际上是一个由Bitmap组成的Drawable
     * @param config 一定要有透明度的Config
     * @param shadowWidth 包含阴影的总宽度
     * @param shadowHeight 包含阴影的总高度
     * @param shadowRadius 阴影宽度
     * @param offsetX 阴影x轴位移
     * @param offsetY 阴影y轴位移
     * @param shadowColor 阴影起始颜色
     * @param rect 内容范围
     * @param bgDrawable 内容的背景
     * @return
     */
    public Drawable generateShadowDrawable(Bitmap.Config config , int shadowWidth, int shadowHeight ,
                                           int shadowRadius, int offsetX, int offsetY, int shadowColor,
                                           Rect rect, Drawable bgDrawable) {
        Bitmap bitmap = Bitmap.createBitmap(shadowWidth, shadowHeight, config);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.TRANSPARENT);

        Paint paint = new Paint();
        paint.setShadowLayer(shadowRadius, offsetX, offsetY, shadowColor);
        canvas.drawRect(new RectF(rect), paint);
        if(bgDrawable != null) {
            bgDrawable.setBounds(rect);
            bgDrawable.draw(canvas);
        }
        return new ShadowDrawable(bitmap,new Rect(0,0,shadowWidth,shadowHeight),offsetX,offsetY);
    }

    public Bitmap getBlurDrawable(int width, int height, int contentWidth, int contentHeight, int shadowColor, int radius, int shadowRadius, int backgroundColor) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(0);

        Paint paint = new Paint();
        paint.setShadowLayer((float) shadowRadius, 0.0f, 0.0f, shadowColor);

        RectF rectF = new RectF((float) ((width / 2) - (contentWidth / 2)), (float) ((height / 2) - (contentHeight / 2)), (float) ((width - (width / 2)) + (contentWidth / 2)), (float) ((height - (height / 2)) + (contentHeight / 2)));
        canvas.drawRoundRect(rectF, (float) radius, (float) radius, paint);
        Paint newPaint = new Paint();
        newPaint.setColor(backgroundColor);
        canvas.drawRoundRect(rectF, (float) radius, (float) radius, newPaint);
        return bitmap;
    }


    private static class ShadowDrawable extends Drawable {
        /**阴影背景图片*/
        Bitmap mBitmap;
        /**阴影范围*/
        Rect mShadowRect;
        int offsetX,offsetY;

        public ShadowDrawable(Bitmap bitmap, Rect shadowRect, int offsetX, int offsetY) {
            mBitmap = bitmap;
            mShadowRect = shadowRect;
            this.offsetX = offsetX;
            this.offsetY = offsetY;
        }

        @Override
        public void draw(@NonNull Canvas canvas) {
            Rect bounds = getBounds();
            Log.e("TAG", "draw: " + bounds);
            canvas.drawBitmap(mBitmap, bounds.width()/2- mShadowRect.width()/2 + offsetX , bounds.height()/2- mShadowRect.height()/2 + offsetY, null);
        }

        @Override
        public void setBounds(int left, int top, int right, int bottom) {
            super.setBounds(left, top, right, bottom);

        }

        @Override
        public void setAlpha(int alpha) {
//            mBitmap.setAlpha(alpha);
        }

        @Override
        public void setColorFilter(@Nullable ColorFilter colorFilter) {
//            mBitmap.setColorFilter(colorFilter);
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSPARENT;
        }
    }

}
